Skip to content

feat(motd): message-of-the-day banner on every pilotctl command#253

Merged
Alexgodoroja merged 4 commits into
mainfrom
feat/motd-message-of-the-day
Jun 16, 2026
Merged

feat(motd): message-of-the-day banner on every pilotctl command#253
Alexgodoroja merged 4 commits into
mainfrom
feat/motd-message-of-the-day

Conversation

@Alexgodoroja

Copy link
Copy Markdown
Collaborator

What

Adds an always-on message of the day (MOTD) notice the pilot team can publish for a single UTC day at a time. It is prepended to every pilotctl command's output, and disappears on its own when cleared.

$ pilotctl info
Message of the day: overlay maintenance 22:00 UTC — expect ~5min blips

<normal pilotctl info output>

Design (fast CLI, no on-demand DB calls)

  • Daemon is the only component that touches the network. New background loop motdPollLoop fetches the feed every --motd-interval (default 15m), selects the entry dated for the current UTC day, holds it in d.motd, and mirrors it to ~/.pilot/motd.json. Modeled on the existing skill-reconciler loop — no new binary ships.
  • pilotctl reads only the local mirror — one file read, no network, no IPC — and re-validates the UTC day on read, so a stale mirror (daemon offline across midnight) never shows yesterday's message.
pilot-motd repo (motd.json) --poll--> pilot-daemon --mirror--> ~/.pilot/motd.json --read--> pilotctl banner

Output

  • text mode: prepends Message of the day: <text>.
  • --json mode: carries it as a top-level important_update envelope field (prepending text would break parsing); also surfaced as motd in pilotctl info.

Clearing is first-class

An empty feed, a removed entry, or a blank text all resolve to a cleared mirror within one poll interval — committing an empty MOTD updates the value just like posting one.

Changes

  • New pure-stdlib leaf package internal/motd (Fetch/Parse/SelectForToday/WriteMirror/ReadActiveMirror) + unit tests (UTC-day selection, stale-mirror rejection, clearing, HTTP fetch).
  • Daemon: motd field, Config.MOTDFeedURL/MOTDInterval, poll loop, mirror path, DaemonInfo.MOTD, info IPC field, --motd-feed-url/--motd-interval flags + PILOT_MOTD_URL.
  • pilotctl: cmd/pilotctl/motd.go reader, banner injection in main(), important_update in output/fatalCode/fatalHint envelopes + tests.
  • layers.yaml: classify internal/motd as a utility leaf.
  • docs/motd.md: operator + design docs.

Feed source

Consumes motd.json from the new pilot-motd repo (separate PR). Default URL: https://raw.githubusercontent.com/pilot-protocol/pilot-motd/main/motd.json.

Test

go build ./..., go vet, and go test ./internal/motd/ ./cmd/pilotctl/ ./pkg/daemon/ all pass. Smoke-tested with built binaries: text banner shows, important_update present in --json, yesterday-dated mirror suppresses the banner.

Add an always-on "message of the day" notice that the pilot team can
publish for a single UTC day at a time. It appears ahead of every
pilotctl command's output, and disappears on its own when cleared.

Design keeps both the CLI and the daemon off the hot path:

  - The daemon is the only component that touches the network. A new
    background loop (motdPollLoop) fetches the feed on --motd-interval
    (default 15m), selects the entry dated for the current UTC day,
    holds it in d.motd, and mirrors it to ~/.pilot/motd.json. Modeled
    on the existing skill-reconciler loop — no new binary ships.
  - pilotctl reads only that local mirror (one file read, no network,
    no IPC) and re-validates the UTC day on read, so a stale mirror
    never shows yesterday's message.

Output:
  - text mode prepends "Message of the day: <text>"
  - --json mode carries it as a top-level important_update envelope
    field (text would break parsing); also surfaced as motd in info.

Clearing is first-class: an empty feed, a removed entry, or a blank
text all resolve to a cleared mirror within one poll interval.

New internal/motd package (pure-stdlib leaf): Fetch, Parse,
SelectForToday, WriteMirror, ReadActiveMirror, with unit tests for
UTC-day selection, stale-mirror rejection, and clearing. Daemon flags
--motd-feed-url / --motd-interval and PILOT_MOTD_URL env override.

Feed source: https://github.com/pilot-protocol/pilot-motd (motd.json).
Alexgodoroja and others added 3 commits June 15, 2026 17:01
Publishing is gated to maintainers with push access to the feed. The doc
now describes only the feature, design, output, configuration, and
semantics — not how to post or clear a message.
@Alexgodoroja Alexgodoroja merged commit e1a4f49 into main Jun 16, 2026
9 checks passed
Alexgodoroja added a commit that referenced this pull request Jun 16, 2026
Adds the message-of-the-day banner (merged via #253). See CHANGELOG for
the full entry.

Co-authored-by: Alex Godoroja <alex@vulturelabs.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant